//
//  WCLayoutManager.m
//  WabbitCode
//
//  Created by William Towe on 2/22/09.
//  Copyright 2009 Revolution Software. All rights reserved.
//

#import "WCLayoutManager.h"
#import "WCMacros.h"
#import "WCAppController.h"
#import "NSArray+WCExtensions.h"


@implementation WCLayoutManager
- (id)init {
	if (!(self = [super init]))
		return nil;
	
	_showInvisibleCharacters = NSUserDefaultsBoolForKey(kWCPrefsEditorDefaultShowInvisibleCharactersKey);
	
	[self setAllowsNonContiguousLayout:NO];
	
	[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.kWCPrefsEditorInvisibleCharacterColorKey" options:NSKeyValueObservingOptionNew context:(void *)kWCPrefsEditorInvisibleCharacterColorKey];
	
	return self;
}

- (void)dealloc {
#ifdef WCDEBUG
	NSLog(@"WCLayoutManager dealloc");
#endif
	
	[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.kWCPrefsEditorInvisibleCharacterColorKey"];
	
	[super dealloc];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
	if ([(NSString *)context isEqualToString:kWCPrefsEditorDefaultShowInvisibleCharactersKey] ||
		[(NSString *)context isEqualToString:kWCPrefsEditorInvisibleCharacterColorKey]) {
		
		[[[[self textContainers] firstObject] textView] setNeedsDisplay:YES];
	}
	else {
		[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
	}
}

- (void)drawGlyphsForGlyphRange:(NSRange)glyphRange atPoint:(NSPoint)containerOrigin {
    if (_showInvisibleCharacters) {
		static NSString *tabCharacter = nil;
		static NSString *newLineCharacter = nil;
		if (!tabCharacter) {
			unichar tab = 0x00ac;
			unichar newLine = 0x00b6;
			tabCharacter = [[NSString alloc] initWithCharacters:&tab length:1];
			newLineCharacter = [[NSString alloc] initWithCharacters:&newLine length:1];
		}
		NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:NSUserDefaultsKeyedUnarchivedObjectForKey(kWCPrefsEditorFontKey), NSFontAttributeName, NSUserDefaultsKeyedUnarchivedObjectForKey(kWCPrefsEditorInvisibleCharacterColorKey), NSForegroundColorAttributeName, nil];
		NSString *completeString = [[self textStorage] string];
		NSUInteger lengthToRedraw = NSMaxRange(glyphRange), index = 0;	
		
		for (index = glyphRange.location; index < lengthToRedraw; index++) {
			unichar characterToCheck = [completeString characterAtIndex:index];
			NSPoint pointToDrawAt = NSZeroPoint;
			NSRect glyphFragment = NSZeroRect;
			
			if (characterToCheck == '\t') {
				pointToDrawAt = [self locationForGlyphAtIndex:index];
				glyphFragment = [self lineFragmentRectForGlyphAtIndex:index effectiveRange:NULL];
				pointToDrawAt.x += glyphFragment.origin.x;
				pointToDrawAt.y = glyphFragment.origin.y;
				[tabCharacter drawAtPoint:pointToDrawAt withAttributes:attributes];
				
			} else if (characterToCheck == '\n' || characterToCheck == '\r') {
				pointToDrawAt = [self locationForGlyphAtIndex:index];
				glyphFragment = [self lineFragmentRectForGlyphAtIndex:index effectiveRange:NULL];
				pointToDrawAt.x += glyphFragment.origin.x;
				pointToDrawAt.y = glyphFragment.origin.y;
				[newLineCharacter drawAtPoint:pointToDrawAt withAttributes:attributes];
			}
		}
    } 
	
    [super drawGlyphsForGlyphRange:glyphRange atPoint:containerOrigin];
}

@synthesize showInvisibleCharacters=_showInvisibleCharacters;

- (void)setShowInvisibleCharacters:(BOOL)flag {
	_showInvisibleCharacters = flag;
	[self setShowsInvisibleCharacters:flag];
}
@end
